package com.ggy.ggyaiagent.agent.model;

import cn.hutool.core.util.StrUtil;
import com.alibaba.dashscope.common.Role;
import com.itextpdf.styledxmlparser.jsoup.internal.StringUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.MessageType;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * 抽象的基础代理类，用于管理代理状态和执行流程。
 * <p>
 * 提供状态转换，内存管理和基于步骤的执行循环的基础功能。
 * 子类必须实现 step 方法。
 */
@Data
@Slf4j
public abstract class BaseAgent {
    //核心属性
    private String name;

    //提示
    private String systemPrompt;
    private String nextStepPrompt;

    //状态-初始空闲
    private AgentState state = AgentState.IDLE;

    //执行控制
    private int maxSteps = 10;
    private int currentStep = 0;

    //LLM
    private ChatClient chatClient;

    //Memory (需要自主维护会话上下文)
    private List<Message> messageList = new ArrayList<>();

    private int duplicateThreshold = 2;

    /**
     * 运行代理（流式输出）
     *
     * @param userPrompt 用户提示词
     * @return SseEmitter实例
     */
    public SseEmitter runStream(String userPrompt,String chatId ) {
        // 创建SseEmitter，设置较长的超时时间
        SseEmitter emitter = new SseEmitter(300000L); // 5分钟超时

        // 使用线程异步处理，避免阻塞主线程
        CompletableFuture.runAsync(() -> {
            try {
                if (this.state != AgentState.IDLE) {
                    emitter.send("错误：无法从状态运行代理: " + this.state);
                    emitter.complete();
                    return;
                }
                if (StringUtil.isBlank(userPrompt)) {
                    emitter.send("错误：不能使用空提示词运行代理");
                    emitter.complete();
                    return;
                }
            } catch (Exception e) {
                emitter.completeWithError(e);
            }
                // 2/ 更改状态
                state = AgentState.RUNNING;
                // 记录消息上下文
                messageList.add(new UserMessage(userPrompt));
            // 保存结果列表
            //List<String> results = new ArrayList<>();
                try {
                    for (int i = 0; i < maxSteps && state != AgentState.FINISHED; i++) {
                        int stepNumber = i + 1;
                        currentStep = stepNumber;
                        log.info("Executing step " + stepNumber + "/" + maxSteps);
                        if(isStuck()){
                            handleStuckState();
                        }
                        // 单步执行
                        String stepResult = step(emitter,chatId);
                        String result = "Step " + stepNumber + ": " + stepResult;
                        //results.add(result);
                        // 发送每一步的结果
                        emitter.send(result+"("+stepNumber + "/" + maxSteps+")");
                    }
                    // 检查是否超出步骤限制
                    if (currentStep >= maxSteps) {
                        state = AgentState.FINISHED;
                        //results.add("Terminated: Reached max steps (" + maxSteps + ")");
                        emitter.send("执行结束: 达到最大步骤 (" + maxSteps + ")");
                    }
                    // 正常完成
                    emitter.complete();
                } catch (Exception e) {
                    state = AgentState.ERROR;
                    log.error("执行智能体失败", e);
                    try {
                        emitter.send("执行错误: " + e.getMessage());
                        emitter.complete();
                    } catch (Exception ex) {
                        emitter.completeWithError(ex);
                    }
                } finally {
                    // 清理资源
                    this.cleanup();
                }

        });

        // 设置超时和完成回调
        emitter.onTimeout(() -> {
            this.state = AgentState.ERROR;
            this.cleanup();
            log.warn("SSE connection timed out");
        });

        emitter.onCompletion(() -> {
            if (this.state == AgentState.RUNNING) {
                this.state = AgentState.FINISHED;
            }
            this.cleanup();
            log.info("SSE connection completed");
        });

        return emitter;
    }

    public boolean isStuck(){
        if (messageList.size() < 2){
            return false;
        }
        Message lastMessage = messageList.get(messageList.size() - 1);
        if(lastMessage.getText() == null || lastMessage.getText().isEmpty()){
            return false;
        }
        //计算重复出现次数
        int duplicateCount = 0;
        for (int i = messageList.size() - 2; i >=0 ; i--) {
            Message msg = messageList.get(i);
            if(msg.getMessageType().equals(MessageType.ASSISTANT) &&
            lastMessage.getText().equals(msg.getText())){
                duplicateCount++;
            }
        }
        return duplicateCount >= duplicateThreshold;
    }

    /**
     * 处理陷入循环的状态
     */
    protected void handleStuckState() {
        String stuckPrompt = "观察到重复响应。考虑新策略，或者直接结束(尽快调用结束方法)，避免已尝试过的无效路径。";
        this.nextStepPrompt = stuckPrompt + "\n" + (this.nextStepPrompt != null ? this.nextStepPrompt : "");
        System.out.println("Agent detected stuck state. Added prompt: " + stuckPrompt);
    }

    
    /**
     * 清理资源
     */
    private void cleanup() {
        //让子类去重写此方法来清理资源。
    }

    /**
     * 执行单个步骤
     *
     * @return
     */
    public abstract String step(SseEmitter emitter,String chatId ) throws IOException;

}
